//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//// PARTICULAR PURPOSE.
////
//// Copyright (c) Microsoft Corporation. All rights reserved

#pragma once
#include "FDefs.h"
#include <queue>
#include "IFragmentController.h"

namespace Microsoft {
	namespace Media {
		namespace FragmentedMediaSink {
			ref class FMediaSinkProxy;

			interface class ISinkCallback
			{
				void OnShutdown();
				void NotifyError(Exception^ ex);
			};

			public ref class FMediaSinkProxy sealed
			{
			public:
				FMediaSinkProxy();
				virtual ~FMediaSinkProxy();

				event EventHandler<String^>^ MediaSinkError;
				
				Windows::Media::IMediaExtension ^GetMFExtensions();

				Windows::Foundation::IAsyncOperation<Windows::Media::IMediaExtension^>^ InitializeAsync(
					Windows::Media::MediaProperties::IMediaEncodingProperties ^audioEncodingProperties,
					Windows::Media::MediaProperties::IMediaEncodingProperties ^videoEncodingProperties,
					Windows::Foundation::Collections::IVector<Microsoft::Media::FragmentedMediaSink::IFragmentController^>^ audioFragmentControllers,
					Windows::Foundation::Collections::IVector<Microsoft::Media::FragmentedMediaSink::IFragmentController^>^ videoFragmentControllers
					);

			internal:


				void SetMediaStreamProperties(
					Windows::Media::Capture::MediaStreamType MediaStreamType,
					_In_opt_ Windows::Media::MediaProperties::IMediaEncodingProperties ^mediaEncodingProperties
					);

			private:
				void NotifyError(Exception^ ex);

				void OnShutdown();

				ref class FSinkCallback sealed : ISinkCallback
				{
				public:
					virtual void OnShutdown()
					{
						_parent->OnShutdown();
					}

					virtual void NotifyError(Exception^ ex)
					{
						_parent->NotifyError(ex);
					}

				internal:
					FSinkCallback(FMediaSinkProxy ^parent)
						: _parent(parent)
					{
					}

				private:
					FMediaSinkProxy ^_parent;
				};

				void CheckShutdown()
				{
					if (_fShutdown)
					{
						Throw(MF_E_SHUTDOWN);
					}
				}

			private:
				CritSec _critSec;
				ComPtr<IMFMediaSink> _spMediaSink;
				bool _fShutdown;
			};
		}
	}
}
